import { VAxios } from './axios'
import { AxiosTransform } from './axiosTransform'
import axios, { AxiosResponse } from 'axios'
import qs from 'qs'
import { checkStatus } from './checkStatus'
import { Modal, message as Message } from 'ant-design-vue'

import { ResultEnum, RequestEnum, ContentTypeEnum } from '@/enums/httpEnum'
import { isString } from '@/utils/is/index'
import { setObjToUrlParams } from '@/utils/urlUtils'
import { RequestOptions, Result } from './types'

const isDev = process.env.NODE_ENV === 'development'
import router from '@/router'
import store from '@/store'
import { Storage } from '@/utils/Storage'
/**
 * @description 处理请求
 */
const transform: AxiosTransform = {
  /**
   * @description 处理请求数据
   */
  transformRequestData: (res: AxiosResponse<Result>, options: RequestOptions) => {
    const {
      isTransformRequestResult,
      isShowMessage,
      isShowErrorMessageText,
      isShowSuccessMessageText,
      successMessageText,
      errorMessageText
    } = options
    const reject = Promise.reject
    const { data } = res
    const { code, result, message } = data
    const hasSuccess = data && Reflect.has(data, 'code') && code === ResultEnum.SUCCESS
    if (isShowMessage) {
      if (hasSuccess && (successMessageText || isShowSuccessMessageText)) {
        Message.success(successMessageText || isShowSuccessMessageText)
      } else if (!hasSuccess && (errorMessageText || isShowErrorMessageText)) {
        Message.error(message || errorMessageText || '操作失败')
      } else if (!hasSuccess && options.errorMessageMode === 'modal') {
        Modal.confirm({ title: '错误提示', content: message })
      }
    }
    if (!isTransformRequestResult) {
      return res.data
    }
    if (!data) {
      return reject(data)
    }
    if (code === ResultEnum.SUCCESS) {
      return result
    }
    if (code === ResultEnum.ERROR) {
      if (message) {
        Message.error(data.message)
        Promise.reject(new Error(message))
      } else {
        const msg = 'error response'
        Message.error(msg)
        Promise.reject(new Error(msg))
      }
      return reject()
    }
    if (code === ResultEnum.TIMEOUT) {
      // todo
    }
    if (!hasSuccess) {
      return reject(new Error(message))
    }
    return data
  },
  // request before interceptors
  beforeRequestHook: (config, options) => {
    const { apiUrl, joinParamsToUrl } = options
    config.url = isDev ? `/api${config.url}` : `${apiUrl || ''}${config.url}`
    if (config.method === RequestEnum.GET) {
      const now = new Date().getTime()
      if (!isString(config.params)) {
        config.data = {
          params: Object.assign(config.params || {}, {
            _t: now
          })
        }
      } else {
        config.url = config.url + config.params + `?_t=${now}`
        config.params = {}
      }
    } else {
      if (!isString(config.params)) {
        config.data = config.params
        config.params = {}
        if (joinParamsToUrl) {
          config.url = setObjToUrlParams(config.url as string, config.data)
        }
      } else {
        config.url = config.url + config.params
        config.params = {}
      }
    }
    return config
  },
  /**
   * @description 请求拦截器
   */
  // requestInterceptors: (config) => {
  //   // todo
  // },
  /**
   * @description 响应拦截器
   */
  responseInterceptorsCatch: (error: any) => {
    const { response, code, message } = error || {}
    const msg: string =
      response && response.data && response.data.error ? response.data.error.message : ''
    const err: string = error.toString()
    try {
      if (code === 'ECONNABORTED' && message.indexOf('timeout') !== -1) {
        Message.error('接口请求超时，请刷新重试')
        return
      }
      if (err && err.includes('Network Error')) {
        Modal.confirm({
          title: '网络异常',
          content: '请检测网络连接'
        })
        return
      }
    } catch (e) {
      throw new Error(e)
    }
    // cancel request
    const isCancel = axios.isCancel(error)
    if (!isCancel) {
      checkStatus(error.response && error.response.status, msg)
    } else {
      console.warn('请求取消')
    }
    return error
  }
}
const Axios = new VAxios({
  timeout: 15 * 1000,
  headers: { 'Content-Type': ContentTypeEnum.FORM_URLENCODED },
  transform,
  requestOptions: {
    joinPrefix: true,
    isTransformRequestResult: true,
    joinParamsToUrl: false,
    formatDate: true,
    errorMessageMode: 'none',
    apiUrl: import.meta.env.BASE_URL as string
  },
  withCredentials: false
})
export default Axios
